package com.solrtest.service.impl;

import com.solrtest.doman.Order;
import com.solrtest.service.BatchSync;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrServerException;
import org.eclipse.jetty.util.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.solr.core.SolrTemplate;
import org.springframework.data.solr.core.query.SimpleQuery;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.stereotype.Service;
import org.thymeleaf.util.DateUtils;

import java.io.IOException;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 批量同步
 */
@Service
public class BatchSyncImpl implements BatchSync {

    private final String coreName = "order";
    private final SolrTemplate solrTemplate;
    private final JdbcTemplate jdbcTemplate;
    private final SolrClient solrClient;

    @Autowired
    public BatchSyncImpl(SolrTemplate solrTemplate, JdbcTemplate jdbcTemplate, SolrClient solrClient) {
        this.solrTemplate = solrTemplate;
        this.jdbcTemplate = jdbcTemplate;
        this.solrClient = solrClient;
    }

    @Override
    public Object readUseTimeOrder(int act) {
        int frequency = 0;//页码
        int readRows = 5000;//读取读数
        int totalRow = 0;//总行数
        boolean stopRead = false;//停止读取状态
        long sTime = System.currentTimeMillis();
        System.out.println("读取开始时间:" + DateUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss", Locale.CHINA));
        switch (act) {
            case 1:
                NamedParameterJdbcTemplate nameJdbc = new NamedParameterJdbcTemplate(jdbcTemplate);
                RowMapper<Order> rm = BeanPropertyRowMapper.newInstance(Order.class);
                String sql = "select * from (select  ROW_NUMBER() OVER(order by oid) as rn,* from erp_order)a where rn between :sRow and :eRow";
                while (!stopRead) {
                    //分页读取
                    Map<String, Integer> paramMap = new HashMap<>();
                    paramMap.put("sRow", frequency * readRows + 1);
                    paramMap.put("eRow", frequency * readRows + readRows);
                    List<Order> list = nameJdbc.query(sql, paramMap, rm);
                    //分页控制
                    if (list.size() > 0) {
                        frequency++;
                        totalRow += list.size();
                        System.out.println(DateUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss", Locale.CHINA) + " Sql:成功读取第[" + frequency + "]页数据,共[" + list.size() + "]条记录" +
                                list.get(0).getOid());
                    } else {
                        stopRead = true;
                    }
                }
                break;
            case 2:
                SimpleQuery query = new SimpleQuery("*:*");
                query.setRows(readRows);
                while (!stopRead) {
                    //分页查询
                    query.setOffset((long) (frequency * readRows));
                    Page<Order> page = solrTemplate.queryForPage(coreName, query, Order.class);
                    //分页控制
                    if (page.getContent().size() > 0) {
                        frequency++;
                        totalRow += page.getContent().size();
                        System.out.println(DateUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss", Locale.CHINA) + " Solr:成功读取第[" + frequency + "]页数据,共[" + page.getContent().size() + "]条记录." +
                                page.getContent().get(0).getOid());
                    } else {
                        stopRead = true;
                    }
                }
                break;
        }
        System.out.println("读取结束时间:" + DateUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss", Locale.CHINA));
        long eTime = System.currentTimeMillis();
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("结果", "读取总记录数为:" + totalRow);
        resultMap.put("读取耗时", (eTime - sTime) / 1000 + "秒");
        return resultMap;
    }

    @Override
    public Object BatchSyncOrder(int act) {
        NamedParameterJdbcTemplate nameJdbc = new NamedParameterJdbcTemplate(jdbcTemplate);
        RowMapper<Order> rm = BeanPropertyRowMapper.newInstance(Order.class); //  where left(oid,4) = '2003'and oid = '2003010000000001'
        String sql = "select * from (select  ROW_NUMBER() OVER(order by oid) as rn,* from erp_order where left(oid,6) = '200301' )a where rn between :sRow and :eRow";

        int processors = Runtime.getRuntime().availableProcessors();
        ExecutorService exec = Executors.newFixedThreadPool(processors + 1);
        int frequency = 0;//页码
        int readRows = 5000;//读取读数
        int totalRow = 0;//总行数
        boolean stopRead = false;//停止读取状态
        long sTime = System.currentTimeMillis();
        System.out.println("开始时间:" + DateUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss", Locale.CHINA));
        while (!stopRead) {
            //分页读取
            Map<String, Integer> paramMap = new HashMap<>();
            paramMap.put("sRow", frequency * readRows + 1);
            paramMap.put("eRow", frequency * readRows + readRows);
            List<Order> list = nameJdbc.query(sql, paramMap, rm);
            System.out.println(sql + " s" + (frequency * readRows + 1) + " e:" + (frequency * readRows + readRows));
            //分页控制
            if (list.size() > 0) {
                switch (act) {
                    case 1:
                        exec.execute(() -> {
                            solrTemplate.saveBeans(coreName, list);
                            solrTemplate.commit(coreName);
                        });
                        break;
                    case 2:
                        exec.execute(() -> {
                            try {
                                solrClient.addBeans(coreName, list);
                                solrClient.commit(coreName);
                            } catch (IOException | SolrServerException e) {
                                e.printStackTrace();
                            }
                        });
                        break;
                }
                frequency++;
                totalRow += list.size();
                System.out.println("第" + frequency + "次读取,第一条订单号:" + list.get(0).getOid() + " 集合大小:" + list.size());
            } else {
                stopRead = true;
            }
        }

        exec.shutdown();
        while (true) {
            if (exec.isTerminated()) {
                System.out.println("所有的子线程都结束了！");
                break;
            }
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        System.out.println("结束时间:" + DateUtils.format(new Date(), "yyyy-MM-dd HH:mm:ss", Locale.CHINA));
        long eTime = System.currentTimeMillis();
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("结果", "读取总记录数为:" + totalRow);
        resultMap.put("耗时", (eTime - sTime) / 1000 + "秒");
        return resultMap;
    }


    @Override
    public Page<Order> queryOrder(Order order) {

        //动态拼接条件 AND 必须大写，并且注意空格只能有一个
        StringBuilder sb = new StringBuilder();
        if (!StringUtil.isEmpty(order.getOid()))
            if (sb.length() == 0)
                sb.append("oid:").append(order.getOid());
            else
                sb.append(" AND oid:").append(order.getOid());

        if (!StringUtil.isEmpty(order.getDeliveryNote()))
            if (sb.length() == 0)
                sb.append("deliveryNote:").append(order.getDeliveryNote());
            else
                sb.append(" AND deliveryNote:").append(order.getDeliveryNote());

        //bwtween 条件
        if (!StringUtil.isEmpty(order.getSDate()) && !StringUtil.isEmpty(order.getEDate()))
            if (sb.length() == 0)
                sb.append("deliveryDate:[").append(order.getSDate()).append(" TO ").append(order.getEDate()).append("]");
            else
                sb.append(" AND deliveryDate:[").append(order.getSDate()).append(" TO ").append(order.getEDate()).append("]");

        //in 条件
        if (!StringUtil.isEmpty(order.getShopIds()))
            if (sb.length() == 0)
                sb.append("shopId:(").append(order.getShopIds().trim().replaceAll(",", " ")).append(")");
            else
                sb.append(" AND shopId:(").append(order.getShopIds().trim().replaceAll(",", " ")).append(")");

        //大于等于
        if (!StringUtil.isEmpty(order.getAmountGt()))
            if (sb.length() == 0)
                sb.append("totalCost:[").append(order.getAmountGt().trim()).append(" TO *]");
            else
                sb.append(" AND totalCost:[").append(order.getAmountGt().trim()).append(" TO *]");

        //小于等于
        if (!StringUtil.isEmpty(order.getAmountLt()))
            if (sb.length() == 0)
                sb.append("totalCost:[* TO ").append(order.getAmountLt().trim()).append("]");
            else
                sb.append(" AND totalCost:[* TO ").append(order.getAmountLt().trim()).append("]");

        SimpleQuery query = new SimpleQuery(sb.length() == 0 ? "*:*" : sb.toString());
        query.setRows(10);
        return solrTemplate.query(coreName, query, Order.class);
    }

    public static void main(String[] args) {


    }

}
